//
//  BMPhotoIO_iOS8Tool.m
//  bigmama
//
//  Created by huyuchen on 2017/9/28.
//  Copyright © 2017年 盛成文化. All rights reserved.
//

#import "BMPhotoIO_iOS8Tool.h"

@interface BMPhotoIO_iOS8Tool ()

// 相册
@property (nonatomic, strong) NSMutableArray *albumArray;
// 只含视频的相册
@property (nonatomic, strong) NSMutableArray *videoAlbumArr;
// 相册配置
@property (nonatomic, strong) PHFetchOptions *assetOptions;
// 相片配置
@property (nonatomic, strong) PHImageRequestOptions *imageOptions;
// 请求iCloud的缩略图
@property (nonatomic, strong) UIImage *iCloudThumbImage;


@end

@implementation BMPhotoIO_iOS8Tool

- (instancetype)init
{
    self = [super init];
    if (self) {
        _maxMB = 5;
    }
    return self;
}

#pragma mark - 懒加载
- (NSMutableArray *)albumArray
{
    if (!_albumArray) {
        _albumArray = [NSMutableArray array];
    }
    return _albumArray;
}

- (NSMutableArray *)videoAlbumArr{
    
    if (!_videoAlbumArr) {
        _videoAlbumArr = [NSMutableArray array];
    }
    return _videoAlbumArr;
}

- (PHFetchOptions *)assetOptions
{
    if (!_assetOptions) {
        _assetOptions = [[PHFetchOptions alloc] init];
        _assetOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];
    }
    return _assetOptions;
}

- (PHImageRequestOptions *)imageOptions
{
    if (!_imageOptions) {
        _imageOptions = [[PHImageRequestOptions alloc] init];
        _imageOptions.synchronous = NO;
        _imageOptions.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
    }
    return _imageOptions;
}


// 读取相册
- (void)selectAlbumWithFinishBlock:(void (^)(id obj))finishBlock videoBlock:(void (^)(id obj))videoBlock;
{
    BMWeakSelf
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        
        // 获取相机胶卷
        [weakSelf selectCameraRoolAlbum];
        
        // 获取相机胶卷里面的视频
        //[weakSelf selectCameraRoolVideo];
        
        // 获取用户相册
        [weakSelf selectUserAlumbsWithFinishBlock:finishBlock videoFinishBlock:videoBlock];
        
        //获取用户其他相册里面的视频
        //[weakSelf selectUserVideoWithFinishBlock:finishBlock];
    });
}

//选择相机胶卷里面的视频
//- (void)selectCameraRoolVideo{
//    // 1.相机胶卷
//    PHFetchResult *cameraRoolResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype: PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil];
//    PHAssetCollection *collection = cameraRoolResult.firstObject;
//
//    // 2.相册模型
//    __block BMPhotoIOAlbumModel *album = [[BMPhotoIOAlbumModel alloc] init];
//    // 名称
//    album.name = collection.localizedTitle;
//    album.collection = collection;
//
//    [self getVideoWithCollection:collection imageBlock:^(UIImage *image) {
//        // 占位图
//        album.holderImage = image;
//    } countBlock:^(NSInteger count) {
//        // 相片数量
//        album.count = count;
//    }];
//    // 3.插入到第一个
//    [self.albumArray insertObject:album atIndex:0];
//
//}

// 初始化相机胶卷
- (void)selectCameraRoolAlbum
{
    // 1.相机胶卷
    PHFetchResult *cameraRoolResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype: PHAssetCollectionSubtypeSmartAlbumUserLibrary options:nil];
    PHAssetCollection *collection = cameraRoolResult.firstObject;
    
    // 2.相册模型
    __block BMPhotoIOAlbumModel *album = [[BMPhotoIOAlbumModel alloc] init];
    // 名称
    album.name = collection.localizedTitle;
    album.collection = collection;
    
    [self getAlbumDataWithCollection:collection imageBlock:^(UIImage *image) {
        // 占位图
        album.holderImage = image;
    } countBlock:^(NSInteger count) {
        // 相片数量
        album.count = count;
    }];
    
    // 3.插入到第一个
    [self.albumArray insertObject:album atIndex:0];
    
    //判断相机胶卷内是否有视频
    __block BMPhotoIOAlbumModel *videoModel = [[BMPhotoIOAlbumModel alloc] init];
    videoModel.name = collection.localizedTitle;
    videoModel.collection = collection;
    [self getVideoWithCollection:collection imageBlock:^(UIImage *image) {
        videoModel.holderImage = image;
    } countBlock:^(NSInteger count) {
        videoModel.count = count;
        [self.videoAlbumArr insertObject:videoModel atIndex:0];
    }];
}

// 初始化用户相册
- (void)selectUserAlumbsWithFinishBlock:(void (^)(id obj))finishBlock videoFinishBlock:(void (^)(id obj))videoFinishBlock;
{
    BMWeakSelf
    PHFetchResult *cameraRoolResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:  PHAssetCollectionSubtypeAlbumRegular | PHAssetCollectionSubtypeAlbumSyncedAlbum | PHAssetCollectionSubtypeAlbumCloudShared options:nil];
    __block NSInteger index = 0; // 索引
    __block NSInteger videoIndex = 0;
    
    for (PHAssetCollection *collection in cameraRoolResult) {
        
//        NSLog(@"name = %@", collection.localizedTitle);
        // 2.相册模型
        __block BMPhotoIOAlbumModel *album = [[BMPhotoIOAlbumModel alloc] init];
        [self.albumArray addObject:album];
        // 2.1 名称
        album.name = collection.localizedTitle;
        album.collection = collection;
        
        [self getAlbumDataWithCollection:collection imageBlock:^(UIImage *image) {
            // 占位图
            album.holderImage = image;
            index++;
            if (index == cameraRoolResult.count) {
                if (finishBlock) {
                    finishBlock(weakSelf.albumArray);
                }
            }
        } countBlock:^(NSInteger count) {
            // 相片数量
            album.count = count;
            if (count == 0) {
                [weakSelf.albumArray removeObject:album];
            }
        }];
        
        //判断其他相册内是否有视频
        __block BMPhotoIOAlbumModel *videoModel = [[BMPhotoIOAlbumModel alloc] init];
        videoModel.name = collection.localizedTitle;
        videoModel.collection = collection;
        [self.videoAlbumArr addObject:videoModel];
        
        [self getVideoWithCollection:collection imageBlock:^(UIImage *image) {
            videoModel.holderImage = image;
            videoIndex++;
            if (videoIndex == cameraRoolResult.count) {
                if (videoFinishBlock) {
                    videoFinishBlock(weakSelf.videoAlbumArr);
                }
            }
        } countBlock:^(NSInteger count) {
            videoModel.count = count;
            if (count == 0) {
                [weakSelf.videoAlbumArr removeObject:videoModel];
            }
        }];
    }
    // 没有只能相册时，只有一个相机胶卷，需要回调
    if (!cameraRoolResult.count) {
        if (videoFinishBlock) {
            videoFinishBlock(weakSelf.videoAlbumArr);
        }
        if (finishBlock) {
            finishBlock(weakSelf.albumArray);
        }
    }
}

//获取用户相册里面含有视频的相册
//- (void)selectUserVideoWithFinishBlock:(void (^)(id obj))finishBlock{
//    PHFetchResult *smartAlbumsFetchResult1 = [PHAssetCollection fetchTopLevelUserCollectionsWithOptions:nil];
//
//    __block NSInteger index = 0; // 索引
//    for (PHAssetCollection *sub in smartAlbumsFetchResult1)
//    {
//        PHFetchResult *fetchResult = [PHAsset fetchAssetsInAssetCollection:sub options:nil];
//        NSInteger videoCount = [fetchResult countOfAssetsWithMediaType:PHAssetMediaTypeVideo];
//
//        //该相册含有视频初始化model
//        __block BMPhotoIOAlbumModel *album = [[BMPhotoIOAlbumModel alloc] init];
//        [self.videoAlbumArr addObject:album];
//        // 2.1 名称
//        album.name = sub.localizedTitle;
//        album.collection = sub;
//        BMWeakSelf
//        [self getVideoWithCollection:sub imageBlock:^(UIImage *image) {
//            album.holderImage = image;
//            index++;
//            if (index == smartAlbumsFetchResult1.count) {
//                if (finishBlock) {
//                    finishBlock(weakSelf.videoAlbumArr);
//                }
//            }
//        } countBlock:^(NSInteger count) {
//            album.count = count;
//            if (count == 0) {
//                [weakSelf.videoAlbumArr removeObject:album];
//            }
//        }];
//    }
//
//}

// 获取图片和相册数量
- (void)getAlbumDataWithCollection:(PHAssetCollection *)collection imageBlock:(void(^)(UIImage *image))imageBlock countBlock:(void(^)(NSInteger count))countBlock
{
    PHFetchResult *assetResult = [PHAsset fetchAssetsInAssetCollection:collection options:self.assetOptions];
    // 相片数量
    if (countBlock) {
        countBlock(assetResult.count);
    }
    
    // 占位图
    PHAsset *holderAsset = assetResult.firstObject;
    // 占位图配置
    PHImageRequestOptions *options = [[PHImageRequestOptions alloc] init];
    options.synchronous = NO;
    options.deliveryMode = PHImageRequestOptionsDeliveryModeHighQualityFormat;
    // Cannot create a large image loader for image formats not supported by hardware decoder
    [[PHImageManager defaultManager] requestImageForAsset:holderAsset targetSize:CGSizeMake(200, 200) contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
        if (imageBlock) {
            imageBlock(result);
        }
    }];
}

//获取相册内视频hoderimage和视频数量
- (void)getVideoWithCollection:(PHAssetCollection *)collection imageBlock:(void (^)(UIImage *image))imageBlock countBlock:(void(^)(NSInteger count))countBlock{
    
    PHFetchResult *assetResult = [PHAsset fetchAssetsInAssetCollection:collection options:self.assetOptions];
    
    NSInteger videoCount = [assetResult countOfAssetsWithMediaType:PHAssetMediaTypeVideo];
    if (videoCount > 0) {
        for (PHAsset *asset in assetResult) {
            //获取第一个视频的截图
            if (asset.mediaType == PHAssetMediaTypeVideo) {
                [[PHImageManager defaultManager]requestImageForAsset:asset targetSize:CGSizeMake(200, 200) contentMode:PHImageContentModeDefault options:nil resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
                    if (imageBlock) {
                        imageBlock(result);
                    }
                }];
                break;
            }
        }
    }else{
        if (imageBlock) {
            imageBlock(nil);
        }
    }
    if (countBlock) {
        countBlock(videoCount);
    }
    
}

- (void)selectPhotosWithCollection:(PHAssetCollection *)collection finishBlcok:(void (^)(id obj1,id obj2))finishBlock
{
    
    if (!finishBlock) {
        NSAssert(1 == 2, @"finishBlock不能为空");
    }
    PHFetchResult *assetResult = [PHAsset fetchAssetsInAssetCollection:collection options:self.assetOptions];
    NSMutableArray *photosArray = [NSMutableArray array];
    if (assetResult.count) {
        for (NSInteger i = 0; i < assetResult.count; i++) {
            PHAsset *asset = assetResult[i];
            if (asset.mediaType != PHAssetMediaTypeImage) {
                // 如果最后一个是视频，那么直接传
                if (i == assetResult.count - 1 && photosArray.count) {
                    finishBlock(photosArray, @(YES));
                    break;
                }
                continue;
            }
            BMPhotoIOPhotoModel *model = [[BMPhotoIOPhotoModel alloc] init];
            model.createDate = asset.creationDate;
            model.asset = asset;
            model.assetID = asset.localIdentifier;
            BMPhotoIOPhotoModel *lastModel = photosArray.lastObject;
            
            if (lastModel) {
                // 有值,判断跟当前模型日期是否相同
                if ([lastModel.createDate yj_isEqualToDateIgnoreTime:model.createDate]) {
                    // 相同日期，直接加入当前组
                    [photosArray addObject:model];
                } else {
                    // 不同日期，那么要传出旧组，创建新租
                    NSMutableArray *newArray = [NSMutableArray arrayWithArray:photosArray];
                    finishBlock(newArray, @(NO));
                    photosArray = [NSMutableArray array];
                    [photosArray addObject:model];
                }
                
            } else {
                // 没有值，证明是组的第一个，直接添加到组
                photosArray = [NSMutableArray array];
                [photosArray addObject:model];
            }
            
            // 最后一张图片
            if (i == assetResult.count - 1 && photosArray.count) {
                finishBlock(photosArray, @(YES));
                return;
            }
        }
    } else {
        finishBlock(photosArray, @(YES));
    }
}

- (void)selectVideosWithCollection:(PHAssetCollection *)collection finishBlock:(void (^)(id obj1,id obj2))finishBlock{
    if (!finishBlock) {
        NSAssert(1 == 2, @"finishBlock不能为空");
    }
    
    __block BMPhotoIOVideoModel *model = nil;
    PHFetchResult *assetResult = [PHAsset fetchAssetsInAssetCollection:collection options:self.assetOptions];
    __block NSMutableArray *photosArray = [NSMutableArray array];
    
    if (![assetResult countOfAssetsWithMediaType:PHAssetMediaTypeVideo]) {
        //没有视频 返回结束
        finishBlock(photosArray, @(YES));
        return;
    }
    
    for (NSInteger i = 0; i < assetResult.count; i++) {
        
        PHAsset *asset = assetResult[i];
        if (asset.mediaType == PHAssetMediaTypeVideo) {
            //只有视频才加入数组
            model = [[BMPhotoIOVideoModel alloc] init];
            model.createDate = asset.creationDate;
            model.asset = asset;
            model.assetID = asset.localIdentifier;
            model.duration = asset.duration;
            BMPhotoIOPhotoModel *lastModel = photosArray.lastObject;
            
            if (lastModel) {
                // 有值,判断跟当前模型日期是否相同
                if ([lastModel.createDate yj_isEqualToDateIgnoreTime:model.createDate]) {
                    // 相同日期，直接加入当前组
                    [photosArray addObject:model];
                } else {
                    // 不同日期，那么要传出旧组，创建新租
                    NSMutableArray *newArray = [NSMutableArray arrayWithArray:photosArray];
                    finishBlock(newArray, @(NO));
                    photosArray = [NSMutableArray array];
                    [photosArray addObject:model];
                }
                
            } else {
                // 没有值，证明是组的第一个，直接添加到组
                photosArray = [NSMutableArray array];
                [photosArray addObject:model];
            }
            
            
        }
        // 最后一张图片
        if (i == assetResult.count - 1 && photosArray.count) {
            finishBlock(photosArray, @(YES));
            return;
        }
    }
}

- (void)thumbImageWithAsset:(PHAsset *)asset finishBlock:(void (^)(id obj))finishBLock
{
    CGSize size = CGSizeMake(200, 200);
    [self imageWithAsset:asset targetSize:size finishBlock:finishBLock];
}

// 根据asset获取要缓存的图片，比缩略图大，比原图小，不模糊
- (void)cacheImageWithAsset:(PHAsset *)asset finishBlock:(void (^)(id obj))finishBLock
{
    CGSize screenSize = [UIScreen mainScreen].bounds.size;
    CGFloat width = screenSize.width * [UIScreen mainScreen].scale;
    CGFloat height = screenSize.height * [UIScreen mainScreen].scale;
    CGSize size = CGSizeMake(width, height);
    //    [self imageWithAsset:asset targetSize:size finishBlock:finishBLock];
    PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init];
    options.resizeMode = PHImageRequestOptionsResizeModeExact;
    options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
    //可以通过网络下载iCloud资源，如果用户开启了系统的内存优化功能，系统在低内存情况下会自动上传本体图片到iCloud，本地仅存储低清资源，如果不开启，那么下面的方法将获取不了所需要尺寸大小的资源，result = nil；
    options.networkAccessAllowed = YES;
    options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"iCloud下载progress ：%f", progress);
        });
    };
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
            BOOL downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
            if (downloadFinined) {
                if (result && finishBLock) {
                    finishBLock(result);
                }
            } else {
                if (finishBLock && !result) {
                    finishBLock([UIImage new]);
                }
            }
        }];
    });
}

- (void)originalImageDataWithAsset:(PHAsset *)asset finishBlock:(void (^)(id obj))finishBLock
{
    CGSize size = CGSizeMake(asset.pixelWidth, asset.pixelHeight);
    PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init];
    options.resizeMode = PHImageRequestOptionsResizeModeExact;
    options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
    //可以通过网络下载iCloud资源，如果用户开启了系统的内存优化功能，系统在低内存情况下会自动上传本体图片到iCloud，本地仅存储低清资源，如果不开启，那么下面的方法将获取不了所需要尺寸大小的资源，result = nil；
    options.networkAccessAllowed = YES;
    options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
        
        NSLog(@"iCloudprogress ：%f error = %@, error.des = %@", progress, error, error.userInfo);
    };
    NSLog(@"assset = %@, type = %zd", asset, asset.mediaType);
    BMWeakSelf
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
            BOOL downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
            if (downloadFinined) {
                // 判断是否下载到了，有可能下载失败
                if (!result) {
                    result = weakSelf.iCloudThumbImage; // 等于缩略图
                }
                NSData *data = UIImageJPEGRepresentation(result, 1.0);
                // 判断是否大于1M
                if (data.length >= 1024 * 1024) {
                    data = UIImageJPEGRepresentation(result, 0.8);
                    // 判断是否大于最大容量
                    if (data.length >= self.maxMB * 1024 * 1024) {
                        data = UIImageJPEGRepresentation(result, 0.5);
                    }
                }
                // 下载成功清除缩略图
                weakSelf.iCloudThumbImage = nil;
                // 回调
                if (finishBLock) {
                    finishBLock(data);
                }
            } else {
                if (result) {
                    // 赋值缩略图
                    weakSelf.iCloudThumbImage = result;
                } else {
                    if (finishBLock) {
                        finishBLock([NSData new]);
                    }
                }
            }
        }];
    });
}

- (void)originalImageWithAsset:(PHAsset *)asset finishBlock:(void (^)(id obj))finishBLock
{
    CGSize size = CGSizeMake(asset.pixelWidth, asset.pixelHeight);
    PHImageRequestOptions *options = [[PHImageRequestOptions alloc]init];
    options.resizeMode = PHImageRequestOptionsResizeModeExact;
    options.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
    //可以通过网络下载iCloud资源，如果用户开启了系统的内存优化功能，系统在低内存情况下会自动上传本体图片到iCloud，本地仅存储低清资源，如果不开启，那么下面的方法将获取不了所需要尺寸大小的资源，result = nil；
    options.networkAccessAllowed = YES;
    options.progressHandler = ^(double progress, NSError *error, BOOL *stop, NSDictionary *info) {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"iCloud下载progress ：%f", progress);
        });
    };
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:size contentMode:PHImageContentModeDefault options:options resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
            BOOL downloadFinined = ![[info objectForKey:PHImageCancelledKey] boolValue] && ![info objectForKey:PHImageErrorKey] && ![[info objectForKey:PHImageResultIsDegradedKey] boolValue];
            if (downloadFinined) {
                if (result && finishBLock) {
                    finishBLock(result);
                }
            } else {
                if (finishBLock && !result) {
                    finishBLock([UIImage new]);
                }
            }
        }];
    });
}

// 根据图片id获取PHAsset对象
- (PHAsset *)getAssetWithID:(NSString *)ID
{
    return [PHAsset fetchAssetsWithLocalIdentifiers:@[ID] options:self.assetOptions].firstObject;
}

- (void)imageWithAsset:(PHAsset *)asset targetSize:(CGSize)targetSize finishBlock:(void (^)(id obj))finishBLock
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:targetSize contentMode:PHImageContentModeDefault options:self.imageOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
            if (finishBLock) {
                finishBLock(result);
            }
        }];
    });
}
@end
